/**
 * 
 */
package us.levk.remote.drmaa.client.impl;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.log4j.Logger;
import org.ggf.drmaa.DrmaaException;
import org.ggf.drmaa.DrmsInitException;
import org.ggf.drmaa.JobInfo;
import org.ggf.drmaa.JobTemplate;
import org.ggf.drmaa.Session;
import org.ggf.drmaa.Version;

import us.levk.remote.drmaa.client.Configuration;
import us.levk.remote.drmaa.common.api.RemoteSession;

/**
 * @author levk
 *
 */
public class SessionImpl implements Session {

  @SuppressWarnings ("unused") private static final transient Logger LOG = Logger.getLogger (SessionImpl.class);

  final Map<URL, Map<Class<?>, Object>> remote;
  UUID session = null;
  URL url = null;

  SessionImpl (Map<URL, Map<Class<?>, Object>> remote) { this.remote = remote; }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#init(java.lang.String)
   */
  @Override public void init (String contact) throws DrmaaException {
    try {
      url = new URL (contact);
      session = ((RemoteSession) remote.get (url).get (RemoteSession.class)).init (Configuration.getConfiguration ().getContact (url));
    } catch (MalformedURLException e) { throw (DrmaaException) new DrmsInitException ().initCause (e); }
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#exit()
   */
  @Override public void exit () throws DrmaaException { 
    ((RemoteSession) remote.get (url).get (RemoteSession.class)).exit (session);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#createJobTemplate()
   */
  @Override public JobTemplate createJobTemplate () throws DrmaaException { 
    return new JobTemplateImpl (remote, ((RemoteSession) remote.get (url).get (RemoteSession.class)).createJobTemplate (session), url);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#deleteJobTemplate(org.ggf.drmaa.JobTemplate)
   */
  @Override public void deleteJobTemplate (JobTemplate jt) throws DrmaaException {
    ((RemoteSession) remote.get (url).get (RemoteSession.class)).deleteJobTemplate (session, ((JobTemplateImpl)jt).template);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#runJob(org.ggf.drmaa.JobTemplate)
   */
  @Override public String runJob (JobTemplate jt) throws DrmaaException {
    return ((RemoteSession) remote.get (url).get (RemoteSession.class)).runJob (session, ((JobTemplateImpl)jt).template);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#runBulkJobs(org.ggf.drmaa.JobTemplate, int, int, int)
   */
  @SuppressWarnings ("rawtypes") @Override public List runBulkJobs (JobTemplate jt, int start, int end, int incr) throws DrmaaException {
    return ((RemoteSession) remote.get (url).get (RemoteSession.class)).runBulkJobs (session, ((JobTemplateImpl)jt).template, start, end, incr);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#control(java.lang.String, int)
   */
  @Override public void control (String jobId, int action) throws DrmaaException {
    ((RemoteSession) remote.get (url).get (RemoteSession.class)).control (session, jobId, action);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#synchronize(java.util.List, long, boolean)
   */
  @SuppressWarnings ("rawtypes") @Override public void synchronize (List jobIds, long timeout, boolean dispose) throws DrmaaException {
    ((RemoteSession) remote.get (url).get (RemoteSession.class)).synchronize (session, jobIds, timeout, dispose);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#wait(java.lang.String, long)
   */
  @Override public JobInfo wait (String jobId, long timeout) throws DrmaaException {
    return new JobInfoImpl (remote, ((RemoteSession) remote.get (url).get (RemoteSession.class)).wait (session, jobId, timeout), url);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#getJobProgramStatus(java.lang.String)
   */
  @Override public int getJobProgramStatus (String jobId) throws DrmaaException {
    return ((RemoteSession) remote.get (url).get (RemoteSession.class)).getJobProgramStatus (session, jobId);
  }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#getContact()
   */
  @Override public String getContact () { return "Contact information is not available"; }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#getVersion()
   */
  @Override public Version getVersion () { return new Version (1, 0); }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#getDrmSystem()
   */
  @Override public String getDrmSystem () { return "DRM system information is not available"; }

  /* (non-Javadoc)
   * @see org.ggf.drmaa.Session#getDrmaaImplementation()
   */
  @Override public String getDrmaaImplementation () { return "DRMAA implementation information is not available"; }
}
